package com.lszl.k11;

import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.lszl.k11.core.MediaCodecFun;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

public class LiveActivity extends AppCompatActivity implements SurfaceHolder.Callback, MediaCodecFun.EncoderListener {

    private SurfaceView mSurfaceView;
    private SurfaceHolder mHolder;
    private Camera mCamera;
    private int mWidth, mHeight;
    private MediaCodecFun mMediaCodecFun;
    private FileOutputStream mFileOutputStream;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_live);
        initViewStyle();
        setH264DataToFile();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        releaseCamera(mCamera);
    }

    @Override
    public void surfaceCreated(@NonNull SurfaceHolder holder) {
        openCamera();
    }

    @Override
    public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder holder) {

    }

    @Override
    public void h264(byte[] data) {
        //Log.e("K11", data.length + "");
        try {
            mFileOutputStream.write(data);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 初始化组件
     */
    private void initViewStyle() {
        mSurfaceView = findViewById(R.id.surface_view);
        mHolder = mSurfaceView.getHolder();
        mHolder.addCallback(this);
    }

    /**
     * 打开相机
     */
    private void openCamera() {
        mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
        //获取相机参数
        Camera.Parameters parameters = mCamera.getParameters();
        List<String> modes = parameters.getSupportedFocusModes();
        if (modes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
        else if (modes.contains(Camera.Parameters.FOCUS_MODE_AUTO))
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
        //获取相机支持的预览的大小
        Camera.Size previewSize = getCameraPreviewSize(parameters);
        mWidth = previewSize.width;
        mHeight = previewSize.height;
        //设置预览格式（也就是每一帧的视频格式）YUV420下的NV21
        parameters.setPreviewFormat(ImageFormat.NV21);
        //设置预览图像分辨率
        parameters.setPreviewSize(mWidth, mHeight);
        //相机旋转90度
        mCamera.setDisplayOrientation(90);
        //配置camera参数
        mCamera.setParameters(parameters);
        try {
            mCamera.setPreviewDisplay(mHolder);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //设置编码
        startEncoder();
        //设置监听获取视频流的每一帧
        mCamera.setPreviewCallback(new Camera.PreviewCallback() {
            @Override
            public void onPreviewFrame(byte[] data, Camera camera) {
                mMediaCodecFun.encoderH264(data);
            }
        });
        //调用startPreview()用以更新preview的surface
        mCamera.startPreview();
    }

    /**
     * 开启编码
     */
    private void startEncoder() {
        mMediaCodecFun = new MediaCodecFun(mWidth, mHeight);
        mMediaCodecFun.setEncoderListener(this);
    }

    /**
     * 保存H264数据到文件中
     */
    private void setH264DataToFile() {
        File file = new File(getExternalCacheDir(), "K11.h264");
        try {
            mFileOutputStream = new FileOutputStream(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取设备支持的最大分辨率
     */
    private Camera.Size getCameraPreviewSize(Camera.Parameters parameters) {
        List<Camera.Size> list = parameters.getSupportedPreviewSizes();
        Camera.Size needSize = null;
        for (Camera.Size size : list) {
            if (needSize == null) {
                needSize = size;
                continue;
            }
            if (size.width >= needSize.width) {
                if (size.height > needSize.height) {
                    needSize = size;
                }
            }
        }
        return needSize;
    }

    /**
     * 关闭相机
     */
    public void releaseCamera(Camera camera) {
        if (camera != null) {
            camera.setPreviewCallback(null);
            camera.stopPreview();
            camera.release();
        }
    }

}